﻿using System;
using Xenta.Entities;

namespace Xenta.Operations
{
    /// <summary>
    /// Represents the custom operation with a result.
    /// </summary>
    /// <typeparam name="TResult">The result type.</typeparam>
    public class CustomOperation<TResult> : Operation<TResult>
    {
        #region Fields

        private readonly Func<IUnitOfWork, TResult> _func;

        #endregion

        #region Ctors

        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        /// <param name="func">The operation function.</param>
        public CustomOperation(Func<IUnitOfWork, TResult> func)
        {
            _func = func;
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out TResult result)
        {
            result = _func(uow);
        }

        #endregion
    }

    /// <summary>
    /// Refreshes an entity state.
    /// </summary>
    /// <typeparam name="TEntity">The type of entity.</typeparam>
    public class RefreshEntity<TEntity> : Operation<TEntity>
        where TEntity : IEntity
    {
        #region Properties

        /// <summary>
        /// Gets or sets the entity to be refreshed.
        /// </summary>
        public TEntity Entity
        {
            get;
            set;
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out TEntity result)
        {
            uow.Refresh(Entity);
            result = Entity;
        }

        #endregion
    }

    /// <summary>
    /// Merges an entity state.
    /// </summary>
    /// <typeparam name="TEntity">The type of entity.</typeparam>
    public class MergeEntity<TEntity> : Operation<TEntity>
        where TEntity : class, IEntity
    {
        #region Properties

        /// <summary>
        /// Gets or sets the entity to be refreshed.
        /// </summary>
        public TEntity Entity
        {
            get;
            set;
        }

        #endregion

        #region Utilities

        protected override void Work(IUnitOfWork uow, out TEntity result)
        {
            result = uow.Merge(Entity);
        }

        #endregion
    }
}
